import * as XLSX from 'xlsx-js-style'
import dayjs from 'dayjs'
import ExcelJS from 'exceljs'

//去重 数组
export function duplicate(arr) {
  if (!Array.isArray(arr)) {
    return
  }
  var array = []
  for (var i = 0; i < arr.length; i++) {
    if (array.indexOf(arr[i]) === -1) {
      array.push(arr[i])
    }
  }

  return array
}

/**
 * 方法说明
 * author: iceyhu
 * description: 异步本地存储
 * @param
 * @return
 * @createTime: DATE_TIME
 */
export const localStorageAsync = {
  setItem: (key, value) =>
    new Promise((resolve, reject) => {
      try {
        localStorage.setItem(key, value)
        resolve('success')
      } catch (error) {
        reject(error)
      }
    }),
  getItem: (key) =>
    new Promise((resolve, reject) => {
      try {
        const value = localStorage.getItem(key)
        resolve(value)
      } catch (error) {
        reject(error)
      }
    }),
  removeItem: (key) =>
    new Promise((resolve, reject) => {
      try {
        localStorage.removeItem(key)
        resolve('success')
      } catch (error) {
        reject(error)
      }
    }),
}
/**
 * xlsx：一个强大的电子表格处理库，支持读取、解析和编写多种电子表格格式
 * file-saver：一个简单的文件保存解决方案，兼容大多数现代浏览器
 * 下载【对象数组】的表格
 * @Author icey
 * @param tableData 要导出的表格数据（需要双向绑定的ref）
 * @Date  2025/7/10 15:00
 * @param fileName 文件名
 * @param columns 表头配置:{[表头key]:[表头名称]}
 * @param sheetName 工作表名
 * @param fileType 文件类型（'xlsx' | 'xlsm' | 'xlsb' | 'xls' | 'xla' | 'biff8' | 'biff5' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'slk' | 'html' | 'dif' | 'rtf' | 'prn' | 'eth' | 'dbf'）
 * @constructor
 */
export const exportSheetOfDictArray = (
  tableData = [],
  columns = {},
  { fileName = 'test', sheetName = 'Sheet1', fileType = 'xlsx' }
) => {
  // 获取表头的键名
  const headers_keys = Object.keys(columns)
  // 按表头过滤要下载的数据
  const excelData =
    tableData.map((record) => {
      const obj = {}
      headers_keys.forEach((key) => {
        const name = columns[key]
        if (record[key]) {
          obj[name] = record[key]
        } else {
          obj[name] = name
        }
      })
      return obj
    }) || []

  console.log('excelData', excelData)

  // 生成工作表：json_to_sheet 把json转换为工作表
  const worksheet = XLSX.utils.json_to_sheet(excelData)

  // 设置表格样式，!cols为列宽
  const options = {
    '!cols': [
      { wch: 4.75 }, // wpx 字段表示以像素为单位，wch 字段表示以字符为单位,hidden 如果为真，则隐藏该列
      { wch: 40.25 },
      { wch: 36 },
      { wch: 13 },
      { wch: 13 },
      { wch: 13 },
      { wch: 13 },
      { wch: 30 },
      { wch: 10 },
    ],
    '!rows': [
      { hpx: 30 }, //  hpx height in screen pixels 磅
      { hpx: 25 },
      { hpx: 30 },
      { hpx: 30 },
      { hpx: 30 },
      { hpx: 30 },
      { hpx: 30 },
      { hpx: 30 },
      { hpx: 30 },
      { hpx: 30 },
      { hpx: 30 },
      { hpx: 30 },
    ],
  }

  // 设置每列的列宽，10代表10个字符，注意中文占2个字符
  worksheet['!cols'] = options['!cols']
  worksheet['!rows'] = options['!rows']

  // 合并单元格
  worksheet['!merges'] = [
    // r: 行号, c: 列号
    { s: { r: 0, c: 0 }, e: { r: 0, c: 8 } },
    { s: { r: 1, c: 0 }, e: { r: 1, c: 8 } },
    { s: { r: 2, c: 0 }, e: { r: 2, c: 1 } },
  ]

  // 设置合并后的单元格的值（可选）
  worksheet['A1'] = { v: '赵一鸣门店货架报价清单', t: 's' } // t: 's' 表示字符串类型
  worksheet['A2'] = {
    v: '此报价为不含税报价，发货前付清货款，去货架以付款信息为准，货款未及时付清导致货架安装不及时，时间顺延',
    t: 's',
  }
  worksheet['A3'] = { v: '门店名称:', t: 's' }
  worksheet['C3'] = { v: '门店负责人：', t: 's' }
  worksheet['D3'] = { v: '' }
  worksheet['E3'] = { v: '' }
  worksheet['F3'] = { v: '' }
  worksheet['G3'] = { v: '' }
  worksheet['H3'] = { v: '' }
  worksheet['I3'] = { v: '' }

  worksheet['A1'].s = {
    alignment: { horizontal: 'center' },
    font: { blod: true, sz: 24 },
  }
  worksheet['A2'].s = {
    alignment: { horizontal: 'center' },
    font: { blod: true, sz: 12 },
  }
  worksheet['A3'].s = {
    alignment: { horizontal: 'center' },
    font: { blod: true, sz: 12 },
  }
  worksheet['C3'].s = {
    alignment: { horizontal: 'center' },
    font: { blod: true, sz: 12 },
  }

  // book_new 新建一个工作簿
  const workbook = XLSX.utils.book_new()

  // book_append_sheet 将工作表添加到工作簿
  XLSX.utils.book_append_sheet(workbook, worksheet, sheetName)

  // 生成 Excel 文件
  const excelBuffer = XLSX.write(workbook, {
    bookType: fileType, // 工作簿类型
    type: 'array', // 输出类型
  })

  console.log('excelBuffer', excelBuffer)

  // 创建 Blob 对象
  const blob = new Blob([excelBuffer], { type: 'application/octet-stream' })

  // 保存文件
  saveAs(blob, `${fileName}.${fileType}`)
}

export function exportXlsx(arr, type, name) {
  const wb = XLSX.utils.book_new()
  const ws = XLSX.utils.aoa_to_sheet(arr)

  XLSX.utils.book_append_sheet(wb, ws, 'Sheet1')
  ws['!merges'] = [
    { s: { r: 0, c: 0 }, e: { r: 0, c: 5 } },
    { s: { r: 1, c: 0 }, e: { r: 1, c: 5 } },
    { s: { r: 2, c: 0 }, e: { r: 2, c: 2 } },
    { s: { r: 2, c: 3 }, e: { r: 2, c: 5 } },
  ]
  ws['!cols'] = [
    { wpx: 50 }, // 第一列宽度为250单位
    { wpx: 200 }, // 第二列宽度为300单位
    { wpx: 100 }, // 第三列宽度为350单位
    { wpx: 50 },
    { wpx: 50 },
    { wpx: 50 },
  ]
  ws['A1'].s = {
    alignment: { horizontal: 'center' },
    font: { blod: true, sz: 24 },
  }
  ws['A2'].s = {
    alignment: { horizontal: 'center' },
    font: { blod: true, sz: 12 },
  }
  ws['A3'].s = {
    alignment: { horizontal: 'center' },
    font: { blod: true, sz: 12 },
  }
  ws['D3'].s = {
    alignment: { horizontal: 'center' },
    font: { blod: true, sz: 12 },
  }
  ws['A4'].s = {
    alignment: { horizontal: 'center' },
    font: { blod: true, color: { rgb: 'ffffff' } },
    fill: { fgColor: { rgb: 'ff6a00' } },
  }
  ws['B4'].s = {
    alignment: { horizontal: 'center' },
    font: { blod: true, color: { rgb: 'ffffff' } },
    fill: { fgColor: { rgb: 'ff6a00' } },
  }
  ws['C4'].s = {
    alignment: { horizontal: 'center' },
    font: { blod: true, color: { rgb: 'ffffff' } },
    fill: { fgColor: { rgb: 'ff6a00' } },
  }
  ws['D4'].s = {
    alignment: { horizontal: 'center' },
    font: { blod: true, color: { rgb: 'ffffff' } },
    fill: { fgColor: { rgb: 'ff6a00' } },
  }
  ws['E4'].s = {
    alignment: { horizontal: 'center' },
    font: { blod: true, color: { rgb: 'ffffff' } },
    fill: { fgColor: { rgb: 'ff6a00' } },
  }
  ws['F4'].s = {
    alignment: { horizontal: 'center' },
    font: { blod: true, color: { rgb: 'ffffff' } },
    fill: { fgColor: { rgb: 'ff6a00' } },
  }

  // 导出工作簿为 Blob 对象
  const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' })

  // 创建一个 Blob 对象
  const blob = new Blob([s2ab(wbout)], { type: 'application/octet-stream' })

  // 使用 Blob 对象创建一个链接
  const link = document.createElement('a')
  link.href = URL.createObjectURL(blob)

  link.download = `${name} - ${type} -${dayjs().format('MM-DD')}.xlsx`

  // 触发下载
  link.click()

  // 清理
  URL.revokeObjectURL(link.href)

  function s2ab(s) {
    const buf = new ArrayBuffer(s.length)
    const view = new Uint8Array(buf)
    for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
    return buf
  }
}

//echart 日期补全
export function setData(dateArr) {
  const getNewDate = (time) => {
    let date = new Date(time).getTime() + 1000 * 60 * 60 * 24
    let Y = new Date(date).getFullYear() + '-'
    let M =
      (new Date(date).getMonth() + 1 < 10
        ? '0' + (new Date(date).getMonth() + 1)
        : new Date(date).getMonth() + 1) + '-'
    let D =
      new Date(date).getDate() < 10
        ? '0' + new Date(date).getDate()
        : new Date(date).getDate()
    return Y + M + D
  }

  //　新日期数组
  let newDateArr = []
  newDateArr.push(dateArr[0], dateArr[dateArr.length - 1])
  let startDate = newDateArr[newDateArr.length - 2].date
  let endDate = newDateArr[newDateArr.length - 1].date
  let startStamp = new Date(startDate).getTime()
  let endStamp = new Date(endDate).getTime()
  let diffCounts = Math.abs(startStamp - endStamp) / 1000 / 60 / 60 / 24
  // 得出倒数第二天和倒数第一天的相差天数，依次递减，直到相差１天，表示是相邻的两天
  for (let index = diffCounts; index > 1; index--) {
    //　根据时间戳得出应该往后加的日期
    getNewDate(newDateArr[newDateArr.length - 2].date)
    //　把新的日期从倒数第二个位置追加到新日期数组
    newDateArr.splice(newDateArr.length - 1, 0, {
      date: getNewDate(newDateArr[newDateArr.length - 2].date),
      count: 0,
    })
  }
  newDateArr.forEach((newItem) => {
    dateArr.forEach((oldItem) => {
      if (newItem.date === oldItem.date) {
        newItem.count = oldItem.count
      }
    })
  })
  // 　　　 console.log('原来的缺失日期',dateArr);
  //       console.log('补全后的日期',newDateArr);
  return newDateArr
}

/**
 * 方法说明
 * author: iceyhu
 * description:  数据字典
 * @param
 * @return
 * @createTime: DATE_TIME
 */
export class DataDictionary {
  constructor() {
    this.data = {}
  }

  set(key, value) {
    this.data[key] = value
  }

  get(key) {
    return this.data[key]
  }
}

/**
 * 方法说明
 * author: iceyhu
 * description: 下载带有图片文件的报表
 * @param {Arrary} headers 表头
 * @param {Array} tableData 被下载的全部表格数据
 * @param {options} Object 表格个性化配置
 * @return
 * @createTime: DATE_TIME
 */
const getBase64Image = (url) => {
  const img = new Image()
  // 因为是网络资源所以会有图片跨域问题产生，此属性可以解决跨域问题，下文详解
  img.setAttribute('crossOrigin', 'anonymous')
  // 如果需要兼容ios，这两个顺序一定不能换，先设置crossOrigin后设置src
  img.src = url
  return new Promise((resolve, reject) => {
    img.onload = () => {
      //canvas基本配置
      const canvas = document.createElement('canvas')
      canvas.width = img.width
      canvas.height = img.height
      const ctx = canvas.getContext('2d')
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
      resolve({
        success: true,
        // canvas.toDataURL的方法将图片的绝对路径转换为base64编码
        base64: canvas.toDataURL(),
      })
    }
    img.onerror = () => {
      reject({ success: false })
    }
  })
}
export const downloadReportWithImage = async (
  headers = [],
  tableData,
  options = {
    fileName: '',
    fileSort: '',
  }
) => {
  console.log('headers', headers)
  const workbook = new ExcelJS.Workbook()
  const worksheet = workbook.addWorksheet('Sheet1')
  // 添加数据
  worksheet.addRow([options.fileName]) // 表格标题
  worksheet.addRow(headers)
  const { fileName, fileSort } = options
  console.log('tableData', tableData)
  if (fileSort == 'detailReport') {
    for (const el of tableData) {
      const row = worksheet.addRow([
        el.storeName, // 门店名称
        // el.systemName, // 所属品牌
        el.areaName, //  所属仓库
        el.lalamove, //  货拉拉
        el.warehouseLalamove, //  仓库货架货拉拉
        el.installationFee, // 安装费卸载
        el.outInstallationFee, // 外装
        el.secondVisit, // 二次上门
        el.thirdVisit, // 三次上门
        el.fourVisit, // 四次上门
        el.companyFee, // 售后-装修问题
        el.brandFee, // 售后-品牌方问题
        el.factoryLssue, // 改货架/退货架费用
        el.customerRefund, // 客户退款
        el.factoryLssue, // 工厂问题
        el.qpReissue, // 欠数破损
        '', // 补发快递单号图 el.courierNumberProofList
        '', // 凭证截图 el.addImgList
        el.payMoney, // 门店实付金额
        el.costMoney, // 门店成本金额
        el.shopFee, // 店铺开支费用
        el.laborCosts, // 人工费用
        el.profit, // 利润
        el.bjdFee, // 报价单运费
        el.card, // 卡号
        el.payTime, // 付款时间
        el.kilometers, // 公里数
        el.thirdIn, // 300以内自装
        el.thirdFiveIn, // 300-500内装
        el.thirdFiveOut, // 300-500外装
        el.fiveIn, // 500外自装
        el.fiveOut, // 500外外装
        el.bfFee, // 补发费
      ])

      const images = Array.isArray(el.courierNumberProofList)
        ? el.courierNumberProofList
        : []

      //   console.log('images', images)

      const images1 = Array.isArray(el.addImgList) ? el.addImgList : []

      const imageHeight = 80
      const imageWidth = 100
      // const gap = 10
      // let totalWidth = images.length * (imageWidth + gap)
      if (images.length > 0) {
        worksheet.getRow(row.number).height = imageHeight + 10
        for (let i = 0; i < images.length; i++) {
          try {
            const base64 = await getBase64Image('https://' + images[i])
            //  通过 base64  将图像添加到工作簿
            const imageId = workbook.addImage({
              base64: base64.base64,
              extension: 'png',
            })
            // worksheet.addImage(imageId, 'E5:H20')
            worksheet.addImage(imageId, {
              tl: {
                col: 16 + i * 0.99, // 控制偏移列位置（让图片横向排列在一格里）
                row: row.number - 1, // 总共多少行
              },
              ext: { width: imageWidth, height: imageHeight },
            })
          } catch (err) {
            console.warn('图片插入失败:', 'https://' + images[i], err)
          }
        }
      } else {
        // worksheet.addImage(null)
        // return
      }

      if (images1.length > 0) {
        worksheet.getRow(row.number).height = imageHeight + 10
        console.log('images1', images1)
        for (let i = 0; i < images1.length; i++) {
          try {
            const base64_01 = await getBase64Image('https://' + images1[i])
            //  通过 base64  将图像添加到工作簿
            const imageId1 = workbook.addImage({
              base64: base64_01.base64,
              extension: 'png',
            })
            // worksheet.addImage(imageId, 'E5:H20')
            worksheet.addImage(imageId1, {
              tl: {
                col: 17 + i * 0.99, // 控制偏移列位置（让图片横向排列在一格里）
                row: row.number - 1,
              },
              ext: { width: imageWidth, height: imageHeight },
            })
          } catch (err) {
            console.warn('图片插入失败:', 'https://' + images1[i], err)
          }
        }
      }
    }
    // 合并单元格
    worksheet.mergeCells('A1:AH1')
  } else if (fileSort == 'otherReport') {
    for (const el of tableData) {
      const row = worksheet.addRow([
        el.systemName, // 所属品牌
        el.whProcureRemark, // 仓库采购费用说明
        el.whProcureMoney, // 仓库采购金额
        el.whProcureNotRemark, // 仓库采购未入成本说明
        el.whProcureNotMoney, // 仓库采购未入成本金额
        el.livingRemark, // 生活费用（房租，吃饭）出差费用（车票、住房）
        el.livingMoney, // 生活费用金额
        '', // 凭证截图 el.addImgList
        el.forkliftRemark, // 叉车费用说明，货拉拉到零食很忙公司
        el.forkliftMoney, // 叉车费用金额
        el.storeAfterRemark, // 快递到3月份以前店铺处理售后费用说明
        el.storeAfterMoney, // 快递到三月以前店铺处理售后费用金额
        el.temporaryWorkerRemark, // 请临时工费用说明
        el.temporaryWorkerMoney, // 请临时工费用金额
        el.returnHuolala, // 货架回仓库货拉拉费用说明
        el.returnHuolalaMoney, // 货架回仓库货拉拉费用金额
        el.whMonthMoney, // 仓库月租金
        el.hunanOfficeRemark, // 湖南办公室费用说明
        el.hunanOfficeMoney, // 金额
        el.tipRemark, // 端头费用说明
        el.tipMoney, // 金额
      ])

      const images = Array.isArray(el.addImgList)
        ? el.addImgList
        : el.addImgList
        ? [el.addImgList]
        : []

      // const images1 = Array.isArray(el.addImgList)? el.addImgList: el.addImgList? [el.addImgList]: []

      const imageHeight = 80
      const imageWidth = 100
      // const gap = 10
      // let totalWidth = images.length * (imageWidth + gap)
      if (images.length > 0) {
        worksheet.getRow(row.number).height = imageHeight + 10
        console.log('images', images)
        for (let i = 0; i < images.length; i++) {
          try {
            const base64 = await getBase64Image('https://' + images[i])
            //  通过 base64  将图像添加到工作簿
            const imageId = workbook.addImage({
              base64: base64.base64,
              extension: 'png',
            })

            worksheet.addImage(imageId, {
              tl: {
                col: 7 + i * 0.99, // 控制偏移列位置（让图片横向排列在一格里）
                row: row.number - 1,
              },
              ext: { width: imageWidth, height: imageHeight },
            })
          } catch (err) {
            console.warn('图片插入失败:', 'https://' + images[i], err)
          }
        }
      }

      // if (images1.length > 0) {
      //   worksheet.getRow(row.number).height = imageHeight + 10
      //   console.log('images1', images1)
      //   for (let i = 0; i < images1.length; i++) {
      //     try {
      //       const base64_01 = await getBase64Image('https://' + images1[i])
      //       //  通过 base64  将图像添加到工作簿
      //       const imageId1 = workbook.addImage({
      //         base64: base64_01.base64,
      //         extension: 'png',
      //       })
      //       // worksheet.addImage(imageId, 'E5:H20')
      //       worksheet.addImage(imageId1, {
      //         tl: {
      //           col: 5 + i * 0.99, // 控制偏移列位置（让图片横向排列在一格里）
      //           row: row.number - 1,
      //         },
      //         ext: { width: imageWidth, height: imageHeight },
      //       })
      //     } catch (err) {
      //       console.warn('图片插入失败:', 'https://' + images1[i], err)
      //     }
      //   }
      // }
    }
    // 合并单元格
    worksheet.mergeCells('A1:U1')
  } else if (fileSort == 'multipleOrder') {
    for (const el of tableData) {
      const row = worksheet.addRow([
        el.afterTime, // 日期
        el.areaName, // 仓库
        el.storeName, // 门店名称
        el.storeTypeName, // 所属品牌
        el.bjdFee, // 报价单运费
        el.fhdFee, // 发货单运费
        el.inInstallFee, // 内安装费
        el.outInstallFee, // 外安装费
        el.secondVisit, // 二次上门
        el.thirdVisit, // 三次上门
        el.customerRefund, // 客户退款
        el.qpReissue, // 欠数破损
        el.secondVisit, // 门店付款金额
        '', // 付款截图 el.payProofList 13
        '', // 凭证截图 el.addImgList 14
        el.remark, // 备注
        el.card, // 卡号
      ])
      const images = Array.isArray(el.payProofList)
        ? el.payProofList
        : el.payProofList
        ? [el.payProofList]
        : []
      const images1 = Array.isArray(el.addImgList)
        ? el.addImgList
        : el.addImgList
        ? [el.addImgList]
        : []

      const imageHeight = 80
      const imageWidth = 100
      // const gap = 10
      // let totalWidth = images.length * (imageWidth + gap)
      if (images.length > 0) {
        worksheet.getRow(row.number).height = imageHeight + 10
        console.log('images', images)
        for (let i = 0; i < images.length; i++) {
          try {
            const base64 = await getBase64Image('https://' + images[i])
            //  通过 base64 将图像添加到工作簿
            const imageId = workbook.addImage({
              base64: base64.base64,
              extension: 'png',
            })

            worksheet.addImage(imageId, {
              tl: {
                col: 13 + i * 0.99, // 控制偏移列位置（让图片横向排列在一格里）
                row: row.number - 1,
              },
              ext: { width: imageWidth, height: imageHeight },
            })
          } catch (err) {
            console.warn('图片插入失败:', 'https://' + images[i], err)
          }
        }
      }

      if (images1.length > 0) {
        worksheet.getRow(row.number).height = imageHeight + 10
        console.log('images1', images1)
        for (let i = 0; i < images1.length; i++) {
          try {
            const base64_01 = await getBase64Image('https://' + images1[i])
            //  通过 base64  将图像添加到工作簿
            const imageId1 = workbook.addImage({
              base64: base64_01.base64,
              extension: 'png',
            })
            // worksheet.addImage(imageId, 'E5:H20')
            worksheet.addImage(imageId1, {
              tl: {
                col: 14 + i * 0.99, // 控制偏移列位置（让图片横向排列在一格里）
                row: row.number - 1,
              },
              ext: { width: imageWidth, height: imageHeight },
            })
          } catch (err) {
            console.warn('图片插入失败:', 'https://' + images1[i], err)
          }
        }
      }
    }
    // 合并单元格
    worksheet.mergeCells('A1:Q1')
  }

  // 自定义样式
  worksheet.getCell('A1').fill = {
    type: 'pattern',
    pattern: 'solid',
    fgColor: { argb: 'FFFF00' },
  }
  worksheet.getCell('A1').font = { bold: true, color: { argb: 'FF0000' } }
  worksheet.getCell('A1').alignment = { horizontal: 'center' }

  // 设置列宽
  headers.forEach((col, index) => {
    if (col == '补发快递单号图' || col == '凭证截图' || col == '付款截图') {
      console.log('index', index)
      worksheet.getColumn(index + 1).width = 50
      worksheet.getColumn(index + 1).width = 50
    } else {
      worksheet.getColumn(index + 1).width = 20
    }
  })

  // worksheet.getColumn(1).width = 20
  // worksheet.getColumn(2).width = 20
  // worksheet.getColumn(3).width = 20
  // worksheet.getColumn(4).width = 20
  // worksheet.getColumn(7).width = 20
  // worksheet.getColumn(8).width = 20
  // worksheet.getColumn(9).width = 20
  // worksheet.getColumn(10).width = 20

  // 导出文件
  const buffer = await workbook.xlsx.writeBuffer()
  const blob = new Blob([buffer], { type: 'application/octet-stream' })
  const link = document.createElement('a')
  link.href = URL.createObjectURL(blob)
  link.download = `${fileName}.xlsx`
  link.click()
}
